#include <algorithm>
#include <benchmark/benchmark.h>

#include <cstddef>
#include <cstring>
#include <random>
#include <string>
#include <vector>

constexpr std::size_t kNumStrings = 5000;
constexpr std::size_t kStringLen  = 1024;

// ----------------- 被测试的三个实现 -----------------
void reverse_by_swap(char* str, std::size_t n) {
    char* begin = str;
    char* end   = str + n - 1;
    while (begin < end) {
        char tmp = *begin;
        *begin   = *end;
        *end     = tmp;
        ++begin;
        --end;
    }
}

void reverse_by_xor(char* str, std::size_t n) {
    char* begin = str;
    char* end   = str + n - 1;
    while (begin < end) {
        *begin ^= *end;
        *end   ^= *begin;
        *begin ^= *end;
        ++begin;
        --end;
    }
}

void reverse_by_std(char* str, std::size_t n) {
    std::reverse(str, str + n);
}

// ----------------- 基准测试准备（生成共享数据集） -----------------
const std::vector<std::string>& GetDataset() {
    static const std::vector<std::string> dataset = [] {
        std::vector<std::string> data(kNumStrings, std::string(kStringLen, '\0'));
        std::mt19937 rng(42);
        std::uniform_int_distribution<unsigned char> dist('A', 'Z');

        for (auto& s : data) {
            for (char& ch : s) {
                ch = static_cast<char>(dist(rng));
            }
        }
        return data;
    }();
    return dataset;
}

// ----------------- 基准测试函数 -----------------
template <typename ReverseFn>
void RunBenchmark(benchmark::State& state, ReverseFn&& func) {
    const auto& base = GetDataset();
    std::vector<std::string> working;
    working.reserve(base.size());

    for (auto _ : state) {
        state.PauseTiming();
        working = base;  // 拷贝原始样本，不计入时间
        state.ResumeTiming();

        for (auto& s : working) {
            func(s.data(), s.size());
        }
    }

    state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) *
                            static_cast<int64_t>(base.size()));
    state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
                            static_cast<int64_t>(base.size()) *
                            static_cast<int64_t>(kStringLen));
}

static void BM_reverse_by_swap(benchmark::State& state) {
    RunBenchmark(state, reverse_by_swap);
}

static void BM_reverse_by_xor(benchmark::State& state) {
    RunBenchmark(state, reverse_by_xor);
}

static void BM_reverse_by_std(benchmark::State& state) {
    RunBenchmark(state, reverse_by_std);
}

BENCHMARK(BM_reverse_by_swap);
BENCHMARK(BM_reverse_by_xor);
BENCHMARK(BM_reverse_by_std);
BENCHMARK_MAIN();